home *** CD-ROM | disk | FTP | other *** search
/ The Original Shareware 1.1 / The Original Shareware (WeMake CDs)(Volume 1.1)(CDs, Inc)(1993).iso / 15 / winwhere.zip / WINWHERE.C < prev    next >
Text File  |  1990-11-22  |  35KB  |  1,026 lines

  1. /*===========================================================================*/
  2. /*                                                                           */
  3. /* File    : WINWHERE.C                                                      */
  4. /*                                                                           */
  5. /* Purpose : File finder for Microsoft Windows 3.0                           */
  6. /*                                                                           */
  7. /* History : 9/14/90 Created by Marc Adler @ Magma Systems                   */
  8. /*                              15 Bodwell Terrace, Millburn NJ, 07041       */
  9. /*                              BBS (201) 912-0668, 2400/1200 baud N-8-1     */
  10. /*                                                                           */
  11. /* WINWHERE 1.0 (c) Copyright 1990 Ziff Communications Co.                   */
  12. /*===========================================================================*/
  13.  
  14. #include <stdlib.h>
  15. #include <ctype.h>
  16. #include <dos.h>
  17. #include <fcntl.h>
  18. #include <io.h>
  19. #include <sys\types.h>
  20. #include <sys\stat.h>
  21. #include <string.h>
  22.  
  23. #ifdef MEWEL
  24. #include "window.h"
  25. #undef  NULL
  26. #define NULL  0
  27. #else
  28. #include <windows.h>
  29. #define _DialogBox    DialogBox
  30. #endif
  31.  
  32. #include "winwhere.h"
  33.  
  34.  
  35. /*
  36.   Structure which contains a file-type/file-spec pairing
  37. */
  38. typedef struct tagFileTypeInfo
  39. {
  40.   char szType[65];
  41.   char szSpec[16];
  42. } FILETYPEINFO;
  43. #define MAXFILETYPES  8
  44. FILETYPEINFO FileTypeInfo[MAXFILETYPES];
  45. int nFileTypes = 0;
  46.  
  47. /*
  48.   Structure which contains the current search parameters
  49. */
  50. typedef struct tagSearchInfo
  51. {
  52.   WORD fFlags;
  53. #define SEARCH_DATE  0x0001
  54. #define DATE_EQ      0x0002
  55. #define DATE_LT      0x0004
  56. #define DATE_GT      0x0008
  57. #define SEARCH_SIZE  0x0010
  58. #define SIZE_EQ      0x0020
  59. #define SIZE_LT      0x0040
  60. #define SIZE_GT      0x0080
  61.  
  62.   DWORD dwSize;
  63.   WORD  wDate;
  64. } SEARCHINFO;
  65. SEARCHINFO SearchInfo;
  66.  
  67. #define ISLEAP(y)  ((y)%4 == 0 && (y)%100 != 0 || (y) % 400 == 0)
  68.  
  69. /*
  70.   List of device names used for validation
  71. */
  72. PSTR pszDevices[] =
  73. {
  74.   "aux",  "com1",  "com2",  "com3",  "com4", "con",
  75.   "lpt1", "lpt2",  "lpt3",  "lpt4",  "nul",  "prn",
  76.   NULL
  77. };
  78.  
  79.  
  80.  
  81. HANDLE hInst = 0;          /* instance handle */
  82. HWND   hFoundListBox;      /* handle to the listbox which saves found files */
  83. WORD   iCurrFileType = 0;  /* index of current file type */
  84.  
  85.  
  86. /*
  87.   Function declarations
  88. */
  89. BOOL FAR PASCAL WinwhereDlgProc(HWND, unsigned, WORD, LONG);
  90. BOOL FAR PASCAL AddTypeDlgProc(HWND, unsigned, WORD, LONG);
  91. BOOL FAR PASCAL GenCommandDlgProc(HWND, unsigned, WORD, LONG);
  92. BOOL FAR PASCAL About(HWND, unsigned, WORD, LONG);
  93. BOOL PASCAL WinwhereDriver(PSTR, HWND, WORD);
  94. BOOL FAR PASCAL FindFilesInDirectory(PSTR, WORD, HWND, HWND);
  95. void UpdateFileTypeCombo(HWND);
  96.  
  97.  
  98. /****************************************************************************/
  99. /*                                                                          */
  100. /* Function : WinMain()                                                     */
  101. /*                                                                          */
  102. /* Purpose  : Main initialization function for a WinApp. All that this one  */
  103. /*            does is to invoke the main dialog box.                        */
  104. /*                                                                          */
  105. /* Returns  : Zero.                                                         */
  106. /*                                                                          */
  107. /****************************************************************************/
  108. int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
  109.   HANDLE hInstance;
  110.   HANDLE hPrevInstance;
  111.   LPSTR  lpCmdLine;
  112.   int    nCmdShow;
  113. {
  114.   FARPROC lpProcWinwhere;
  115.  
  116.   hInst = hInstance;
  117.   lpProcWhere = MakeProcInstance(WhereDlgProc, hInstance);
  118.   _DialogBox(hInst, "Where", NULL, lpProcWhere);
  119.   return 0;
  120. }
  121.  
  122.  
  123. /****************************************************************************/
  124. /*                                                                          */
  125. /* Function : WinwhereDlgProc()                                             */
  126. /*                                                                          */
  127. /* Purpose  : The dialog box procedure for the main "winwhere" dialog box.  */
  128. /*                                                                          */
  129. /* Returns  : TRUE if we processed the message, FALSE if not.               */
  130. /*                                                                          */
  131. /****************************************************************************/
  132. BOOL FAR PASCAL WinwhereDlgProc(hDlg, message, wParam, lParam)
  133.   HWND hDlg;
  134.   unsigned message;
  135.   WORD wParam;
  136.   LONG lParam;
  137. {
  138.   FARPROC lpProc;
  139.   int     rc, i;
  140.   char    szBuf[80];
  141.   char    *s;
  142.  
  143.   static int iDaysInMonth[12] =
  144.   {
  145.     31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  146.   };
  147.  
  148.  
  149.   switch (message)
  150.   {
  151.     case WM_INITDIALOG :
  152.       /*
  153.         We want to have an icon associated with this dialog box if the
  154.         user chooses to minimize the dialog box. We load the "winwhere"
  155.         icon from the resource file, and stick it into the hIcon
  156.         field in the dialog box's class structure.
  157.       */
  158. #ifndef MEWEL
  159.       SetClassWord(hDlg, GCW_HICON, LoadIcon(hInst, "Winwhere"));
  160. #endif
  161.  
  162.       hFoundListBox = GetDlgItem(hDlg, ID_FOUNDLIST);
  163.       UpdateFileTypeCombo(GetDlgItem(hDlg, ID_FILETYPE));
  164.       SendDlgItemMessage(hDlg, ID_FILETYPE, CB_SETCURSEL,
  165.                          iCurrFileType = 0, 0L);
  166.  
  167.       EnableWindow(GetDlgItem(hDlg, ID_FINDOPTS), FALSE);
  168.  
  169.       EnableWindow(GetDlgItem(hDlg, ID_DATE), FALSE);
  170.       EnableWindow(GetDlgItem(hDlg, ID_EARLYDATE), FALSE);
  171.       EnableWindow(GetDlgItem(hDlg, ID_LATERDATE), FALSE);
  172.       EnableWindow(GetDlgItem(hDlg, ID_EQUALDATE), FALSE);
  173.  
  174.       EnableWindow(GetDlgItem(hDlg, ID_SIZE), FALSE);
  175.       EnableWindow(GetDlgItem(hDlg, ID_LARGERSIZE), FALSE);
  176.       EnableWindow(GetDlgItem(hDlg, ID_SMALLERSIZE), FALSE);
  177.       EnableWindow(GetDlgItem(hDlg, ID_EQUALSIZE), FALSE);
  178.  
  179.       /*
  180.         Determine which drives are present in the system
  181.       */
  182.       SendDlgItemMessage(hDlg, ID_DRIVELIST, LB_DIR,
  183.                          0xC000, (LONG) (LPSTR) "~~~.~~~");
  184.  
  185.       SetFocus(GetDlgItem(hDlg, ID_FILENAME));
  186.       SetDlgItemText(hDlg, ID_FILENAME, FileTypeInfo[0].szSpec);
  187.       SendDlgItemMessage(hDlg, ID_FILENAME, EM_SETSEL, 
  188.                                NULL, MAKELONG(0, 0x7FFF));
  189.  
  190.       return FALSE;   /* Indicates the focus is set to a control */
  191.  
  192.  
  193.     case WM_COMMAND:
  194.       switch (wParam)
  195.       {
  196.         case ID_BYSIZE  :
  197.           if (IsDlgButtonChecked(hDlg, ID_BYSIZE))
  198.           {
  199.             EnableWindow(GetDlgItem(hDlg, ID_SIZE), TRUE);
  200.             EnableWindow(GetDlgItem(hDlg, ID_LARGERSIZE), TRUE);
  201.             EnableWindow(GetDlgItem(hDlg, ID_SMALLERSIZE), TRUE);
  202.             EnableWindow(GetDlgItem(hDlg, ID_EQUALSIZE), TRUE);
  203.             CheckRadioButton(hDlg, ID_SMALLERSIZE, ID_EQUALSIZE, ID_EQUALSIZE);
  204.             SetFocus(GetDlgItem(hDlg, ID_SIZE));
  205.           }
  206.           else
  207.           {
  208.             EnableWindow(GetDlgItem(hDlg, ID_SIZE), FALSE);
  209.             EnableWindow(GetDlgItem(hDlg, ID_LARGERSIZE), FALSE);
  210.             EnableWindow(GetDlgItem(hDlg, ID_SMALLERSIZE), FALSE);
  211.             EnableWindow(GetDlgItem(hDlg, ID_EQUALSIZE), FALSE);
  212.           }
  213.           break;
  214.  
  215.         case ID_BYDATE  :
  216.           if (IsDlgButtonChecked(hDlg, ID_BYDATE))
  217.           {
  218.             EnableWindow(GetDlgItem(hDlg, ID_DATE), TRUE);
  219.             EnableWindow(GetDlgItem(hDlg, ID_EARLYDATE), TRUE);
  220.             EnableWindow(GetDlgItem(hDlg, ID_LATERDATE), TRUE);
  221.             EnableWindow(GetDlgItem(hDlg, ID_EQUALDATE), TRUE);
  222.             CheckRadioButton(hDlg, ID_EARLYDATE, ID_EQUALDATE, ID_EQUALDATE);
  223.             SetFocus(GetDlgItem(hDlg, ID_DATE));
  224.           }
  225.           else
  226.           {
  227.             EnableWindow(GetDlgItem(hDlg, ID_DATE), FALSE);
  228.             EnableWindow(GetDlgItem(hDlg, ID_EARLYDATE), FALSE);
  229.             EnableWindow(GetDlgItem(hDlg, ID_LATERDATE), FALSE);
  230.             EnableWindow(GetDlgItem(hDlg, ID_EQUALDATE), FALSE);
  231.           }
  232.           break;
  233.  
  234.  
  235.         case ID_FILETYPE:
  236.            switch (HIWORD(lParam))
  237.            {
  238.              case CBN_SELCHANGE :
  239.                /*
  240.                  When the current selection in the file-type combo box
  241.                  changes, we extract the file spec and put it into
  242.                  the edit field.
  243.                */
  244.                iCurrFileType = (int) 
  245.                  SendDlgItemMessage(hDlg, ID_FILETYPE, CB_GETCURSEL, 0, 0L);
  246.                SetDlgItemText(hDlg, ID_FILENAME,
  247.                               FileTypeInfo[iCurrFileType].szSpec);
  248.                SendDlgItemMessage(hDlg, ID_FILENAME, EM_SETSEL,
  249.                                   NULL, MAKELONG(0, 0x7FFF));
  250.                break;
  251.            }
  252.            return TRUE;
  253.  
  254.  
  255.         case ID_ADDFILE :
  256.           lpProc = MakeProcInstance(AddTypeDlgProc, hInst);
  257.           rc = _DialogBox(hInst, "AddType", hDlg, lpProc);
  258.           FreeProcInstance(lpProc);
  259.  
  260.           if (rc == TRUE)
  261.           {
  262.             UpdateFileTypeCombo(GetDlgItem(hDlg, ID_FILETYPE));
  263.             SendDlgItemMessage(hDlg, ID_FILETYPE, CB_SETCURSEL,
  264.                               iCurrFileType = 0, 0L);
  265.             SetFocus(GetDlgItem(hDlg, ID_FILENAME));
  266.             SetDlgItemText(hDlg, ID_FILENAME, FileTypeInfo[0].szSpec);
  267.             SendDlgItemMessage(hDlg, ID_FILENAME, EM_SETSEL,
  268.                                NULL, MAKELONG(0, 0x7FFF));
  269.           }
  270.  
  271.           break;
  272.  
  273.         case ID_FINDOPTS :
  274.           lpProc = MakeProcInstance(GenCommandDlgProc, hInst);
  275.           rc = _DialogBox(hInst, "GenCommand", hDlg, lpProc);
  276.           FreeProcInstance(lpProc);
  277. #ifdef MEWEL
  278.           if (rc == ID_EXEC)
  279.           {
  280.             WinDraw(hDlg);
  281.           }
  282. #endif
  283.           break;
  284.  
  285.  
  286.         case IDOK     :
  287.           /*
  288.             The user pressed the OK button, and wants to start a search.
  289.             Gather up all of the values which the user input, and call
  290.             the search driver.
  291.           */
  292.           GetDlgItemText(hDlg, ID_FILENAME, szBuf, sizeof(szBuf));
  293.           if (!szBuf[0])
  294.           {
  295.             MessageBox(hDlg, "No filename specified.", "Error",
  296.                        MB_OK | MB_ICONHAND);
  297.             return TRUE;
  298.           }
  299.  
  300.           /*
  301.             Do a little validation on the file name
  302.           */
  303.           for (s = szBuf;  *s;  s++)
  304.           {
  305.             if (strchr("|<>[]:+=;,\"/", *s))
  306.             {
  307.               MessageBox(hDlg, "Illegal character in file name.", "Error",
  308.                          MB_OK | MB_ICONHAND);
  309.               return TRUE;
  310.             }
  311.           }
  312.  
  313.           /*
  314.             There is a small anomaly in the findfirst() function. If we
  315.             specify the name of a device (ie- PRN, AUX), then it will be
  316.             found in *every* subdirectory. So, weed out device names.
  317.             Note - we just check against the reserved DOS device names,
  318.             and not against devices which are installed in config.sys.
  319.           */
  320.           for (i = 0;  pszDevices[i] != NULL;  i++)
  321.             if ((s = strstr(szBuf, pszDevices[i])) == szBuf)
  322.             {
  323.               /*
  324.                 The initial part of the filename matches the device.
  325.                 We must weed out filenames like "AUX" or "AUX.FOO",
  326.                 but not filenames like "AUXIL.C".
  327.               */
  328.               s = szBuf + strlen(pszDevices[i]);
  329.               if (*s == '\0' || *s == '.')
  330.               {
  331.                 MessageBox(hDlg, "You cannot specify the name of a device",
  332.                            "Error", MB_OK | MB_ICONHAND);
  333.                 return TRUE;
  334.               }
  335.             }
  336.  
  337.  
  338.           memset((char *) &SearchInfo, 0, sizeof(SearchInfo));
  339.  
  340.           if (IsDlgButtonChecked(hDlg, ID_BYDATE))
  341.           {
  342.             char szDate[32], *pTok;
  343.             int  month = 0, day = 0, year = 0;
  344.  
  345.             GetDlgItemText(hDlg, ID_DATE, szDate, sizeof(szDate));
  346.             if (!szDate[0])
  347.             {
  348.               MessageBox(hDlg, "No date specified.", "Error",
  349.                          MB_OK | MB_ICONHAND);
  350.               return TRUE;
  351.             }
  352.  
  353.             if ((pTok = strtok(szDate, "/-")) != NULL)
  354.               month = atoi(pTok);
  355.             if ((pTok = strtok(NULL, "/-")) != NULL)
  356.               day = atoi(pTok);
  357.             if ((pTok = strtok(NULL, "/-")) != NULL)
  358.               year = atoi(pTok);
  359.  
  360.             if (!month || !day || !year)
  361.             {
  362. date_err:
  363.               MessageBox(hDlg, "Incorrect date specified. Must be mm/dd/yy.",
  364.                                "Error", MB_OK | MB_ICONHAND);
  365.               return TRUE;
  366.             }
  367.  
  368.             /*
  369.               Do a little date validation here
  370.             */
  371.             if (year >= 1900)
  372.               year -= 1900;
  373.             if (year >= 80)
  374.               year -= 80;
  375.             if (month <= 0 || month > 12   ||
  376.                 day < 1    || day > iDaysInMonth[month-1] ||
  377.                 year < 0   || year >= 2000 ||
  378.                 (month == 2 && day == 29 && !ISLEAP(year + 80)))
  379.               goto date_err;
  380.  
  381.  
  382.             /*
  383.               Turn the date into a word-length value which is the same
  384.               format as the date field in the structure returned by
  385.               the _dos_findfirst and _dos_findnext functions.
  386.             */
  387.             SearchInfo.wDate = (day & 0x1F) |
  388.                                ((month & 0x0F) << 5) |
  389.                                ((year & 0x7F) << 9);
  390.  
  391.             SearchInfo.fFlags |= SEARCH_DATE;
  392.             if (IsDlgButtonChecked(hDlg, ID_EARLYDATE))
  393.               SearchInfo.fFlags |= DATE_LT;
  394.             else
  395.             if (IsDlgButtonChecked(hDlg, ID_LATERDATE))
  396.               SearchInfo.fFlags |= DATE_GT;
  397.             else
  398.               SearchInfo.fFlags |= DATE_EQ;
  399.           }
  400.  
  401.           if (IsDlgButtonChecked(hDlg, ID_BYSIZE))
  402.           {
  403.             char szSize[32];
  404.             GetDlgItemText(hDlg, ID_SIZE, szSize, sizeof(szSize));
  405.             if (!szSize[0])
  406.             {
  407.               MessageBox(hDlg, "No size specified.",
  408.                          "Error", MB_OK | MB_ICONHAND);
  409.               return TRUE;
  410.             }
  411.             SearchInfo.dwSize = atol(szSize);
  412.  
  413.             /*
  414.               Do a little size validation. Check for negative numbers,
  415.               and for illegal characters in the size string.
  416.             */
  417.             if (SearchInfo.dwSize < 0)
  418.             {
  419. size_err:
  420.               MessageBox(hDlg, "Invalid size specified.",
  421.                          "Error", MB_OK | MB_ICONHAND);
  422.               return TRUE;
  423.             }
  424.             for (s = szSize;  *s;  s++)
  425.               if (!isdigit(*s))
  426.                 goto size_err;
  427.  
  428.  
  429.             SearchInfo.fFlags |= SEARCH_SIZE;
  430.             if (IsDlgButtonChecked(hDlg, ID_SMALLERSIZE))
  431.               SearchInfo.fFlags |= SIZE_LT;
  432.             else
  433.             if (IsDlgButtonChecked(hDlg, ID_LARGERSIZE))
  434.               SearchInfo.fFlags |= SIZE_GT;
  435.             else
  436.               SearchInfo.fFlags |= SIZE_EQ;
  437.           }
  438.  
  439.           WinwhereDriver(szBuf, hDlg, ID_DRIVELIST);
  440.  
  441.           break;
  442.  
  443.         case IDCANCEL :
  444.           /*
  445.             The user wants to leave the program...
  446.           */
  447.           EndDialog(hDlg, 0);
  448.           break;
  449.  
  450.         case ID_HELP :
  451.           /*
  452.             Display the "About" box
  453.           */
  454.           lpProc = MakeProcInstance(About, hInst);
  455.           _DialogBox(hInst, "About", hDlg, lpProc);
  456.           FreeProcInstance(lpProc);
  457.           break;
  458.       }
  459.       return TRUE;
  460.  
  461.     default:
  462.       return FALSE;
  463.   }
  464. }
  465.  
  466.  
  467. /****************************************************************************/
  468. /*                                                                          */
  469. /* Function : WinwhereDriver                                                */
  470. /*                                                                          */
  471. /* Purpose  : Main driver for the search engine.                            */
  472. /*                                                                          */
  473. /* Returns  : TRUE if files were located, FALSE if not.                     */
  474. /*                                                                          */
  475. /****************************************************************************/
  476. BOOL PASCAL WinwhereDriver(PSTR szSearchSpec, HWND hDlg, WORD idDriveListBox)
  477. {
  478.   HWND hDriveListBox;
  479.   WORD wItem;
  480.   HCURSOR hOldCursor;
  481.   char szFileSpec[128];
  482.   char chDrive;
  483.   int  afDriveMask[26];
  484.   int  nSelected;
  485.   BOOL bContinue = TRUE;
  486.  
  487.   /*
  488.     Get the handle to the directory listbox, and the number of
  489.     entries in the listbox.
  490.   */
  491.   hDriveListBox = GetDlgItem(hDlg, idDriveListBox);
  492.  
  493.  
  494.   /* 
  495.     Disable run button & change cursor to hourglass
  496.   */
  497.   EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
  498.   hOldCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
  499.             
  500.   /*
  501.     Erase the contents of the listbox so that we may put the found
  502.     file names in there.
  503.   */
  504.   SendMessage(hFoundListBox, WM_SETREDRAW, FALSE, 0L);
  505.   SendMessage(hFoundListBox, LB_RESETCONTENT, 0, 0L);
  506.  
  507.   /*
  508.     If no drives were selected, then search the current directory
  509.   */
  510.   if (SendMessage(hDriveListBox, LB_GETSELCOUNT, 0, 0L) == 0)
  511.   {
  512.     FindFilesInDirectory(szSearchSpec, _A_NORMAL, hFoundListBox,
  513.                          GetDlgItem(hDlg, ID_PATH));
  514.     goto bye;
  515.   }
  516.  
  517.  
  518.   /*
  519.     Search all of the drives for the desired file
  520.   */
  521.   /*
  522.     Determine which drives are present in the system
  523.   */
  524.   nSelected = SendMessage(hDriveListBox, LB_GETSELITEMS, 26, 
  525.                           (DWORD) (LPSTR) afDriveMask);
  526.   for (wItem = 0;  wItem < nSelected;  wItem++)
  527.   {
  528.     SendMessage(hDriveListBox, LB_GETTEXT, afDriveMask[wItem],
  529.                                       (LONG)(LPSTR) szFileSpec);
  530.     chDrive = szFileSpec[2];
  531.     sprintf(szFileSpec, "%c:\\%s", chDrive, szSearchSpec);
  532.     bContinue = FindFilesInDirectory(szFileSpec, _A_NORMAL, 
  533.                             hFoundListBox, GetDlgItem(hDlg, ID_PATH));
  534.  
  535.   }
  536.  
  537.   /*
  538.     Check for null search operation
  539.   */
  540. bye:
  541.   if (SendMessage(hFoundListBox, LB_GETCOUNT, 0, 0L) == 0L)
  542.     MessageBox(hDlg, "No files found matching criteria!", 
  543.                      "Winwhere", MB_OK);
  544.   else
  545.   {
  546.     EnableWindow(hFoundListBox, TRUE);
  547.     EnableWindow(GetDlgItem(hDlg, ID_FINDOPTS), TRUE);
  548.   }
  549.                
  550.   /* 
  551.     Activate redrawing
  552.     Restore cursor & repaint display
  553.   */
  554.   SendMessage(hFoundListBox, WM_SETREDRAW, TRUE, 0L);
  555.   SetCursor(hOldCursor);
  556.   EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
  557.   InvalidateRect(hFoundListBox, NULL, TRUE);
  558.   UpdateWindow(hFoundListBox);
  559.   InvalidateRect(GetDlgItem(hDlg, ID_PATH), NULL, TRUE);
  560.   UpdateWindow(GetDlgItem(hDlg, ID_PATH));
  561. }
  562.  
  563.  
  564. /****************************************************************************/
  565. /*                                                                          */
  566. /* Function : FindFilesInDirectory()                                        */
  567. /*                                                                          */
  568. /* Purpose  : Searches a single directory for files who match the search    */
  569. /*            criteria. Recurses on subdirectories.                         */
  570. /*                                                                          */
  571. /* Returns  : TRUE if we sould continue the search.                         */
  572. /*                                                                          */
  573. /****************************************************************************/
  574. BOOL FAR PASCAL FindFilesInDirectory(PSTR szFileSpec, WORD wAttributes, 
  575.                                      HWND hListBox, HWND hPath)
  576. {
  577.    BOOL bContinue;           
  578.    BOOL bDirOutput;          
  579.    BOOL bFound;
  580.    char szPath[64];          
  581.    char szSpec[64];          
  582.    char szEntry[64];         
  583.    PSTR pSlash;
  584.    HDC  hDC;
  585.    RECT r;
  586.    struct find_t ff;   
  587.  
  588.    /* initialization */
  589.    bContinue = TRUE;
  590.    bDirOutput = FALSE;
  591.  
  592.    /*
  593.      Print a little message in the static path field
  594.    */
  595.    hDC = GetDC(hPath);
  596.    GetClientRect(hPath, &r);
  597.    FillRect(hDC, &r, GetStockObject(WHITE_BRUSH));
  598.    if ((pSlash = strrchr(szFileSpec, '\\')) != NULL)
  599.    {
  600.      *pSlash = '\0';
  601.      strcpy(szPath, szFileSpec);
  602.      strcpy(szSpec, pSlash+1);
  603.    }
  604.    else
  605.    {
  606.      strcpy(szPath, ".");
  607.      strcpy(szSpec, szFileSpec);
  608.    }
  609.    TextOut(hDC, 0, 0, strlwr(szFileSpec), strlen(szFileSpec));
  610.    if (pSlash)
  611.      *pSlash = '\\';
  612.    ReleaseDC(hPath, hDC);
  613.  
  614.       
  615.    /*
  616.      Look at all of the normal files which match the file spec.
  617.    */
  618.    if (_dos_findfirst(szFileSpec, wAttributes, &ff) == 0)
  619.    {
  620.      do
  621.      {
  622.        bFound = TRUE;
  623.  
  624.        if (SearchInfo.fFlags & SEARCH_SIZE)
  625.        {
  626.          if ((SearchInfo.fFlags & SIZE_LT) && ff.size >= SearchInfo.dwSize ||
  627.              (SearchInfo.fFlags & SIZE_GT) && ff.size <= SearchInfo.dwSize ||
  628.              (SearchInfo.fFlags & SIZE_EQ) && ff.size !=SearchInfo.dwSize)
  629.            bFound = FALSE;
  630.        }
  631.        if (SearchInfo.fFlags & SEARCH_DATE)
  632.        {
  633.          if ((SearchInfo.fFlags & DATE_LT) && ff.wr_date >= SearchInfo.wDate ||
  634.              (SearchInfo.fFlags & DATE_GT) && ff.wr_date <= SearchInfo.wDate ||
  635.              (SearchInfo.fFlags & DATE_EQ) && ff.wr_date !=SearchInfo.wDate)
  636.            bFound = FALSE;
  637.        }
  638.  
  639.        if (bFound)
  640.        {
  641.          /*
  642.            Add the found file to the listbox. Use the complete path name.
  643.          */
  644.          sprintf(szEntry, "%s\\%s", szPath, ff.name);
  645.          strlwr(szEntry);
  646.          if (SendMessage(hListBox, LB_INSERTSTRING, -1,
  647.                                     (LONG)(LPSTR) szEntry) < 0)
  648.          {
  649.            MessageBox(GetParent(hListBox), "Insufficient Memory!", 
  650.                                  "File Finder", MB_OK | MB_ICONHAND);
  651.            return FALSE;
  652.          }
  653.        }
  654.      } while (_dos_findnext(&ff) == 0);
  655.    } 
  656.    
  657.    /*
  658.      We need to recurse on any subdirectories which were found.
  659.    */
  660.    sprintf(szEntry, "%s\\*.*", szPath);
  661.    if (_dos_findfirst(szEntry, _A_SUBDIR, &ff) == 0)
  662.      do
  663.      {
  664.        if (ff.attrib == _A_SUBDIR && ff.name[0] != '.')
  665.        {
  666.          sprintf(szEntry, "%s\\%s\\%s", szPath, ff.name, szSpec);
  667.          bContinue = FindFilesInDirectory(szEntry, wAttributes,
  668.                                           hListBox, hPath);
  669.        }
  670.      } while (bContinue && _dos_findnext(&ff) == 0);
  671.    
  672.  
  673.    return bContinue;
  674. }
  675.  
  676.  
  677. /****************************************************************************/
  678. /*                                                                          */
  679. /* Function : GenCommandDlgProc()                                           */
  680. /*                                                                          */
  681. /* Purpose  : Dialog box proc for the find-options dialog box.              */
  682. /*                                                                          */
  683. /* Returns  : TRUE if we processed the message, FALSE if not.               */
  684. /*                                                                          */
  685. /****************************************************************************/
  686. BOOL FAR PASCAL GenCommandDlgProc(hDlg, message, wParam, lParam)
  687.   HWND hDlg;
  688.   unsigned message;
  689.   WORD wParam;
  690.   LONG lParam;
  691. {
  692.   HWND hListBox;
  693.   char szBuf[128];
  694.   int  nSelected, i;
  695.  
  696.  
  697.   switch (message)
  698.   {
  699.     case WM_INITDIALOG :
  700.       /*
  701.         Transfer the filenames from the main dialog box's listbox
  702.         to this listbox. Initially select all strings in the listbox.
  703.       */
  704.       hListBox = GetDlgItem(hDlg, ID_FOUNDLIST);
  705.       nSelected = SendMessage(hFoundListBox, LB_GETCOUNT, 0, 0L);
  706.       for (i = 0;  i < nSelected;  i++)
  707.       {
  708.         SendMessage(hFoundListBox, LB_GETTEXT,
  709.                     i, (LONG) (LPSTR) szBuf);
  710.         SendMessage(hListBox, LB_INSERTSTRING, -1, (LONG) (LPSTR) szBuf);
  711.         SendMessage(hListBox, LB_SETSEL, TRUE, MAKELONG(i, 0));
  712.       }
  713.  
  714.       return TRUE;
  715.  
  716.     case WM_COMMAND:
  717.       switch (wParam)
  718.       {
  719.         case IDOK     :
  720.         {
  721.           int  aiIndex[128];
  722.           char szName[65];
  723.           char szCmd[128];
  724.           char *pCmd, *pBuf;
  725.           char szBatchFile[65];
  726.           int  fd;
  727.           OFSTRUCT OF;
  728.  
  729.           GetDlgItemText(hDlg, ID_BATCHFILE, szBatchFile, sizeof(szBatchFile));
  730.           if (szBatchFile[0] == '\0')
  731.           {
  732.             MessageBox(hDlg, "You must input the name of a batch file",
  733.                              "Error", MB_OK | MB_ICONHAND);
  734.             return TRUE;
  735.           }
  736.  
  737.           GetDlgItemText(hDlg, ID_COMMAND, szCmd, sizeof(szCmd));
  738.           if (szCmd[0] == '\0')
  739.           {
  740.             MessageBox(hDlg, "You must input a command",
  741.                              "Error", MB_OK | MB_ICONHAND);
  742.             return TRUE;
  743.           }
  744.  
  745.           hListBox = GetDlgItem(hDlg, ID_FOUNDLIST);
  746.           nSelected = SendMessage(hListBox,
  747.                                   LB_GETSELITEMS,
  748.                                   sizeof(aiIndex)/sizeof(int),
  749.                                   (DWORD) (LPSTR) aiIndex);
  750.           if (nSelected <= 0)
  751.           {
  752.             MessageBox(hDlg, "You must select at least one file",
  753.                              "Error", MB_OK);
  754.             return TRUE;
  755.           }
  756.  
  757.           /*
  758.             Create the batch file.
  759.           */
  760.           fd = OpenFile(szBatchFile, &OF, OF_CREATE | OF_WRITE);
  761.           if (fd < 0)
  762.           {
  763.             sprintf(szBuf,
  764.                     "Couldn't open the batch file %s [Code %d]", 
  765.                     szBatchFile, OF.nErrCode);
  766.             MessageBox(hDlg, szBuf, "Open Error", MB_OK);
  767.             return TRUE;
  768.           }
  769.  
  770.           /*
  771.             For all of the selected files, generate a command string and
  772.             write it to the specified batch file.
  773.           */
  774.           for (i = 0;  i < nSelected;  i++)
  775.           {
  776.             SendMessage(hListBox, LB_GETTEXT,
  777.                         aiIndex[i], (LONG)(LPSTR) szName);
  778.             /*
  779.               Substitute the '!' with the name of the file
  780.             */
  781.             for (pCmd = szCmd, pBuf = szBuf;  *pCmd;  )
  782.               if (*pCmd == '!')
  783.               {
  784.                 strcpy(pBuf, szName);
  785.                 pBuf = szBuf + strlen(szBuf);
  786.                 pCmd++;
  787.               }
  788.               else
  789.                 *pBuf++ = *pCmd++;
  790.             *pBuf++ = '\r';
  791.             *pBuf++ = '\n';
  792.             *pBuf = '\0';
  793.  
  794.             _lwrite(fd, szBuf, strlen(szBuf));
  795.           }
  796.  
  797.           _lclose(fd);
  798.  
  799.           /*
  800.             Perhaps the user wants to execute the batch file?
  801.           */
  802.           if (MessageBox(hDlg, "Do you want to execute the batch file now?",
  803.                                "Batch file written", MB_YESNO) == IDYES)
  804.           {
  805.             if ((pCmd = strchr(szBatchFile, '.')) != NULL)
  806.               *pCmd = '\0';       /* get rid of the .BAT extension */
  807.             WinExec(szBatchFile, 1);
  808.             EndDialog(hDlg, ID_EXEC);
  809.           }
  810.           else
  811.             EndDialog(hDlg, TRUE);
  812.           break;
  813.         } 
  814.  
  815.         case IDCANCEL :
  816.           EndDialog(hDlg, 0);
  817.           break;
  818.       }
  819.       return TRUE;
  820.  
  821.     default:
  822.       return FALSE;
  823.   }
  824. }
  825.  
  826.  
  827. /****************************************************************************/
  828. /*                                                                          */
  829. /* Function : AddTypeDlgProc                                                */
  830. /*                                                                          */
  831. /* Purpose  : Dialog box proc for the dialog box which lets the user add    */
  832. /*            a filetype/filespec pairing to the current list.              */
  833. /*                                                                          */
  834. /* Returns  : TRUE if we processed the message, FALSE if not.               */
  835. /*                                                                          */
  836. /****************************************************************************/
  837. BOOL FAR PASCAL AddTypeDlgProc(hDlg, message, wParam, lParam)
  838.   HWND hDlg;
  839.   unsigned message;
  840.   WORD wParam;
  841.   LONG lParam;
  842. {
  843.   char  szType[65];
  844.   char  szSpec[65];
  845.  
  846.   switch (message)
  847.   {
  848.     case WM_INITDIALOG :
  849.       return TRUE;
  850.  
  851.     case WM_COMMAND:
  852.       switch (wParam)
  853.       {
  854.         case IDOK     :
  855.           /*
  856.             Get the file type string
  857.           */
  858.           GetDlgItemText(hDlg, ID_FILETYPE, szType, sizeof(szType));
  859.           if (szType[0] == '\0')
  860.           {
  861.             MessageBox(hDlg, "You must input a file type", "Error", MB_OK);
  862.             return TRUE;
  863.           }
  864.  
  865.           /*
  866.             Get the file spec string
  867.           */
  868.           GetDlgItemText(hDlg, ID_FILENAME, szSpec, sizeof(szSpec));
  869.           if (szSpec[0] == '\0')
  870.           {
  871.             MessageBox(hDlg, "You must input a file specification",
  872.                              "Error", MB_OK | MB_ICONHAND);
  873.             return TRUE;
  874.           }
  875.           
  876.           /*
  877.             Add the pair to the filetype list
  878.           */
  879.           AddFileType(szType, szSpec);
  880.  
  881.           EndDialog(hDlg, TRUE);
  882.           break;
  883.  
  884.         case IDCANCEL :
  885.           EndDialog(hDlg, FALSE);
  886.           break;
  887.       }
  888.       return TRUE;
  889.  
  890.     default:
  891.       return FALSE;
  892.   }
  893. }
  894.  
  895.  
  896. /****************************************************************************/
  897. /*                                                                          */
  898. /* Function : AddFileType()                                                 */
  899. /*                                                                          */
  900. /* Purpose  : Adds the two passed strings to the list of filetypes          */
  901. /*                                                                          */
  902. /* Returns  : TRUE if added, FALSE if not.                                  */
  903. /*                                                                          */
  904. /****************************************************************************/
  905. AddFileType(PSTR szType, PSTR szSpec)
  906. {
  907.   int   i;
  908.   char  szBuf[256];
  909.  
  910.   if (nFileTypes < MAXFILETYPES)
  911.   {
  912.     /*
  913.       Add it to the array as the last element.
  914.     */
  915.     strcpy(FileTypeInfo[nFileTypes].szType, szType);
  916.     strcpy(FileTypeInfo[nFileTypes].szSpec, szSpec);
  917.     nFileTypes++;
  918.  
  919.     /*
  920.       Create one long string which consists of all the filetypes and
  921.       filespecs. Each string is separated by a blank. We write
  922.       this string to the WIN.INI file.
  923.     */
  924.     szBuf[0] = '\0';
  925.     for (i = 0;  i < nFileTypes;  i++)
  926.     {
  927.       strcat(szBuf, FileTypeInfo[i].szType);
  928.       strcat(szBuf, " ");
  929.       strcat(szBuf, FileTypeInfo[i].szSpec);
  930.       strcat(szBuf, " ");
  931.     }
  932.  
  933.     WriteProfileString("Winwhere", "FileTypes", szBuf);
  934.     return TRUE;
  935.   }
  936.   else
  937.     return FALSE;
  938. }
  939.  
  940.  
  941. /****************************************************************************/
  942. /*                                                                          */
  943. /* Function : UpdateFileTypeCombo()                                         */
  944. /*                                                                          */
  945. /* Purpose  : Reads the filetype/filespec pairs from the WIN.INI file,      */
  946. /*            and adds them to the filetype combo box.                      */
  947. /*                                                                          */
  948. /* Returns  : Nothing.                                                      */
  949. /*                                                                          */
  950. /****************************************************************************/
  951. void UpdateFileTypeCombo(HWND hCombo)
  952. {
  953.   int  i;
  954.   char szBuf[256], *pTok;
  955.  
  956.   /*
  957.     Read the long filetype/filespec string from the WIN.INI file.
  958.   */
  959.   GetProfileString("Winwhere", "FileTypes", "Anything *.*", szBuf,           
  960.                     sizeof(szBuf));
  961.  
  962.   /*
  963.     Extract the pairs and add them to the filetype list
  964.   */
  965.   nFileTypes = 0;
  966.   if ((pTok = strtok(szBuf, " ")) != NULL)
  967.     strcpy(FileTypeInfo[nFileTypes].szType, pTok);
  968.   while (pTok)
  969.   {
  970.     if ((pTok = strtok(NULL, " ")) != NULL)
  971.     {
  972.       strcpy(FileTypeInfo[nFileTypes++].szSpec, pTok);
  973.       if ((pTok = strtok(NULL, " ")) != NULL)
  974.         strcpy(FileTypeInfo[nFileTypes].szType, pTok);
  975.     }
  976.   }
  977.  
  978.   /*
  979.     Refresh the filetype combobox in the main dialog box.
  980.   */
  981.   SendMessage(hCombo, CB_RESETCONTENT, 0, 0L);
  982.   for (i = 0;  i < nFileTypes;  i++)
  983.     SendMessage(hCombo, CB_ADDSTRING, 0,
  984.                (LONG) (LPSTR) FileTypeInfo[i].szType);
  985. }
  986.  
  987.  
  988. /****************************************************************************/
  989. /*                                                                          */
  990. /* Function :  About                                                        */
  991. /*                                                                          */
  992. /* Purpose  :  Dialog box proc for the about box.                           */
  993. /*                                                                          */
  994. /* Returns  : TRUE if we processed the message, FALSE if not.               */
  995. /*                                                                          */
  996. /****************************************************************************/
  997. BOOL FAR PASCAL About(HWND hDlg, unsigned message, WORD wParam, LONG lParam)
  998. {
  999.   switch (message)
  1000.   {
  1001.     case WM_INITDIALOG:
  1002.       return TRUE;
  1003.  
  1004.     case WM_COMMAND:
  1005.       if (wParam == IDOK)
  1006.       {
  1007.         EndDialog(hDlg, TRUE);
  1008.         return TRUE;
  1009.       }
  1010.       break;
  1011.   }
  1012.   return FALSE;
  1013. }
  1014.  
  1015.  
  1016. #ifdef MEWEL
  1017. main()
  1018. {
  1019.   WinInit();
  1020.   WinUseSysColors(NULLHWND, TRUE);
  1021.   return WinMain(NULL, NULL, (LPSTR) NULL, TRUE);
  1022. }
  1023. #endif
  1024.  
  1025.  
  1026.